﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;

using SimbaRGVMonitor.Models;

namespace SimbaRGVMonitor.Views.Components
{
    partial class MonitorScheduleCanvas
    {
        private const int robotWidth = 35;
        private const int robotHeight = 20;

        internal void UpdateRobot(Robot robot)
        {
            Point location;
            var robotNo = robot.RobotNo;
            var robotItem = robotItems[robotNo];
            if (CalculateRobotLocation(robot, out location) == false)
            {
                return;
            }

            var yaw = robot.Yaw;
            robotItem.RenderTransform =
                new RotateTransform
                {
                    Angle = yaw * -1,
                    CenterX = robotItem.Width / 2,
                    CenterY = robotItem.Height / 2
                };
            robotItem.ResetRobot(robot, location);
        }

        internal void ResetRobots(Robot[] robots)
        {
            var updateRobots = robots.Where(item => robotItems.ContainsKey(item.RobotNo)).ToArray();
            foreach(var robot in updateRobots)
            {
                UpdateRobot(robot);
            }
        }

        private bool CalculateRobotLocation(Robot robot, out Point location)
        {
            var px = robot.Px;
            var py = robot.Py;
            var x = Math.Round(px * MapHRate, 2);
            var y = Math.Round(py * MapVRate, 2);

            var robotNo = robot.RobotNo;
            var left = MapLeft + x;
            var top = canvas.ActualHeight - MapTop - y;

            var vertex = vertexItems.Values.FirstOrDefault(item => item.ArriveRobotNo == robotNo);
            if (vertex != null)
            {
                if(vertex.ellipse.HasActualHeight() == false)
                {
                    location = new Point();
                    return false;
                }

                left += (vertex.Width - robotWidth) / 2;
                top += (vertex.ellipse.ActualHeight - robotHeight) / 2;
            }
            else
            {
                left -= robotWidth / 2;
                top -= robotHeight / 2;
            }

            location = new Point(left, top);
            return true;
        }

        private void InitializeRobotItems()
        {
            const int width = 35;
            const int height = 20;
            const int defaultRobotCount = 5;
            for (var i = 0; i < defaultRobotCount; i++)
            {
                var robotNo = (i + 1).ToString().PadLeft(3, '0');

                const int px = 0;
                const int py = 0;
                const int yaw = 0;
                const int packetState = 1;
                var moveStatus = string.Empty;
                var taskAction = string.Empty;
                var currentVertex = string.Empty;
                var taskStatus = RobotStatus.Normal.ToString();

                var x = 20 + i * (width + 10);
                var y = canvas.ActualHeight - 10 - height;
                var location = new Point(x, y);
                var robot = new Robot(robotNo, moveStatus, px, py, currentVertex, yaw, taskAction, taskStatus, packetState);
                var robotItem = new RobotItem() { Width = width, Height = height, Name = "Current" + robotNo };
                robotItem.ResetRobot(robot, location);

                robotItems.Add(robotNo, robotItem);
                canvas.Children.Add(robotItem);
            }
        }
    }
}
